home *** CD-ROM | disk | FTP | other *** search
/ START Magazine / START VOL 4 NO 1.st / POGOSRC.ARC / CREATURE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1985-11-20  |  8.2 KB  |  552 lines

  1.  
  2. /* Creature.c - the parts of Pogo that take care of spawning and 
  3.   evolving and killing creatures.  Also the routines for creatures to
  4.   find other creatures.
  5.   */
  6.  
  7. #include <stdio.h>
  8. #include "pogo.h"
  9. #include "dlist.h"
  10.  
  11. #define CMAX 256
  12.  
  13. extern void *askmem();
  14. extern int creature_count;
  15.  
  16. struct pogo_op *cr_code[CMAX];
  17. union pt_int *cr_data[CMAX];
  18. int cr_datasize[CMAX];
  19. char cr_state[CMAX];
  20. struct func_frame *cr_fuf[CMAX];
  21. Tlist **type_alive;
  22. Tlist *cr_tels;
  23. int get_ta;
  24. int cur_pid;
  25.  
  26. #define CR_EMPTY 0
  27. #define CR_KILLING 1
  28. #define CR_RUNNING 2
  29.  
  30. int cr_count;
  31. int cr_hi = 1;
  32.  
  33. void *
  34. linkt(list, t)
  35. Tlist *list, *t;
  36. {
  37. if (list == NULL)
  38.     {
  39.     t->next = t;
  40.     t->prev = t;
  41.     return(t);
  42.     }
  43. else
  44.     {
  45.     list->prev->next = t;
  46.     t->prev = list->prev;
  47.     list->prev = t;
  48.     t->next = list;
  49.     return(list);
  50.     }
  51. }
  52.  
  53. void *
  54. unlinkt(list, t)
  55. Tlist *list;
  56. register Tlist *t;
  57. {
  58. if (t == list)    /* remove head ... it's easy */
  59.     {
  60.     if (t->next == t)        /* all alone in the world??? */
  61.         return(NULL);
  62.     t->next->prev = t->prev;
  63.     t->prev->next = t->next;
  64.     return(t->next);
  65.     }
  66. else    /* remove non-head (so can assume at least 2 els in list */
  67.     {
  68.     t->next->prev = t->prev;
  69.     t->prev->next = t->next;
  70.     return(list);
  71.     }
  72. }
  73.  
  74. add_type(type, id)
  75. int type, id;
  76. {
  77. register Tlist *t;
  78.  
  79. t = cr_tels+id;
  80. t->id = id;
  81. type_alive[type] = linkt(type_alive[type], t);
  82. }
  83.  
  84.  
  85. free_type(type, id)
  86. int type,id;
  87. {
  88. Tlist *t;
  89.  
  90. type_alive[type] = unlinkt(type_alive[type], cr_tels+id);
  91. }
  92.  
  93. alloc_type_alive()
  94. {
  95. if (get_ta && creature_count)
  96.     {
  97.     if ((type_alive = beg_zero(creature_count*sizeof(Tlist *))) == NULL)
  98.         return(0);
  99.     if ((cr_tels = beg_mem(CMAX*sizeof(Tlist))) == NULL)
  100.         {
  101.         freemem(type_alive);
  102.         type_alive = NULL;
  103.         return(0);
  104.         }
  105.     }
  106. return(1);
  107. }
  108.  
  109.  
  110. go_spawn(p)
  111. union pt_int *p;
  112. {
  113. int i, dsize, dbsize;
  114. union pt_int *data;
  115. struct func_frame *fuf;
  116.  
  117. if (cr_count >= CMAX-1)
  118.     return(0);
  119. for (i=1; i<CMAX; i++)
  120.     {
  121.     if (cr_state[i] == CR_EMPTY)
  122.         {
  123.         fuf = p[-5].p;
  124.         cr_datasize[i] = dsize = fuf->dcount + SECRETS;
  125.         dbsize = (dsize * sizeof(union pt_int)); 
  126.         if ((cr_data[i] = data = askmem(dbsize)) == NULL)
  127.             return(-1);
  128.         zero_bytes(data, dbsize);
  129.         data[CID].i = i;    /* Set id */
  130.         data[CNEW].i = 1;    /* Set NewBorn */
  131.         data[CNAME].p = fuf->name;    /* Set MyName */
  132.         data[CTYPE].i = fuf->crtype;
  133.         if (get_ta)
  134.             add_type(fuf->crtype, i);
  135.         copy_pts(p-4, data+4, 4);    /* copy over x, y, dx, dy */
  136.         cr_code[i] = fuf->code;
  137.         cr_state[i] = CR_RUNNING;
  138.         cr_fuf[i] = fuf;
  139.         if (i >= cr_hi)
  140.             cr_hi = i+1;
  141.         cr_count++;
  142.         return(i);
  143.         }
  144.     }
  145. }
  146.  
  147.  
  148.  
  149.  
  150. static
  151. free_cr_strings(dd, sym)
  152. union pt_int *dd;
  153. Symbol *sym;
  154. {
  155. while (sym != NULL)
  156.     {
  157.     if (sym->type == STRING)
  158.         gentle_free(dd[sym->doff].p);
  159.     sym = sym->next;
  160.     }
  161. }
  162.  
  163. static killi(i)
  164. int i;
  165. {
  166. union pt_int *dd;
  167. struct func_frame *fuf;
  168.  
  169.  
  170. cr_code[i] = NULL;
  171. dd = cr_data[i];
  172. fuf = cr_fuf[i];
  173. if (fuf->got_strings)
  174.     {
  175.     free_cr_strings(dd+SECRETS, fuf->symbols);
  176.     }
  177. if (get_ta)
  178.     free_type(dd[CTYPE].i, i);
  179. freemem(dd);
  180. cr_data[i] = NULL;    /* flushes out bugs */
  181. cr_count -= 1;
  182. cr_state[i] = CR_EMPTY;
  183. if (i == cr_hi-1)
  184.     {
  185.     cr_hi -= 1;
  186.     }
  187. }
  188.  
  189. go_evolve(dstack)
  190. union pt_int *dstack;
  191. {
  192. union pt_int *dd;
  193. int dsize;
  194. int i;
  195.  
  196.  
  197. for (i=1; i<cr_hi; i++)
  198.     {
  199.     cur_pid = i;
  200.     switch (cr_state[i])
  201.         {
  202.         case CR_KILLING:
  203.             {
  204.             killi(i);
  205.             }
  206.             break;
  207.         case CR_RUNNING:
  208.             {
  209.             dd = cr_data[i];
  210. #ifdef DEBUG
  211.             if (dd[0].i != i)
  212.                 {
  213.                 puts("Creature id fucked up");
  214.                 printf("should be %d but is %d\n", i, dd[0].i);
  215.                 run_abort = 1;
  216.                 return;
  217.                 }
  218. #endif DEBUG
  219.             dsize = cr_datasize[i];
  220.             copy_pts(dd, dstack, dsize);
  221.             run_ops(cr_code[i], dstack+SECRETS);
  222.             copy_pts(dstack, dd, dsize);
  223.             dd[1].i++;
  224.             dd[2].i = 0;
  225.             if (run_abort)
  226.                 break;
  227.             }
  228.         }
  229.     }
  230. cur_pid = 0;
  231. }
  232.  
  233. /* This code breaks here if sizeof(pt_int) != sizeof(long) */
  234. copy_pts(s, d, count)
  235. register long *s, *d;
  236. register int count;
  237. {
  238. while (--count >= 0)
  239.     *d++ = *s++;
  240. }
  241.  
  242. cexists(cr)
  243. int cr;
  244. {
  245. return (cr > 0 && cr <= cr_hi && cr_state[cr] == CR_RUNNING);
  246. }
  247.  
  248. check_valid_creature(s, cr)
  249. char *s;
  250. int cr;
  251. {
  252. if (cexists(cr) )
  253.     return(1);
  254. else
  255.     {
  256.     no_such_creature(s, cr);
  257.     return(0);
  258.     }
  259. }
  260.  
  261.  
  262. go_kill(cr)
  263. int cr;
  264. {
  265. union pt_int *data;
  266.  
  267. if (!check_valid_creature("Kill", cr))
  268.     return;
  269. cr_state[cr] = CR_KILLING;
  270. }
  271.  
  272. kill_all()
  273. {
  274. int i;
  275. union pt_int *dd;
  276.  
  277. for (i=1; i<CMAX; i++)
  278.     {
  279.     if (cr_state[i] != CR_EMPTY)
  280.         {
  281.         killi(i);
  282.         }
  283.     }
  284. cr_hi = 1;
  285. cr_count = 0;
  286. }
  287.  
  288. fclosestt(p)
  289. union pt_int *p;
  290. {
  291. Tlist *dd, *head;
  292. int i, x, y;
  293. register int dx, dy;
  294. int closest;
  295. long distance, d;
  296. union pt_int *cdata;
  297. int me;
  298. int cix;
  299.  
  300. distance = 1L<<30;
  301. closest = 0;
  302. me = p[-3].i;
  303. x = p[-2].i;
  304. y = p[-1].i;
  305. head = dd = type_alive[me];
  306. if (dd != NULL)
  307.     {
  308.     for (;;)
  309.         {
  310.         cix = dd->id;
  311.         if (cr_state[cix] == CR_RUNNING)
  312.             {
  313.             cdata = cr_data[cix];
  314.             dx = x - cdata[CX].i;
  315.             dy = y - cdata[CY].i;
  316.             if (dx < 0)
  317.                 dx = -dx;
  318.             if (dy < 0)
  319.                 dy = -dy;
  320.             d = dx + dy;
  321.             if (d < distance)
  322.                 {
  323.                 closest = cix;
  324.                 distance = d;
  325.                 }
  326.             }
  327.         dd = dd->next;
  328.         if (dd == head)
  329.             break;
  330.         }
  331.     }
  332. return(closest);
  333. }
  334.  
  335. void *
  336. do_cread(p)
  337. union pt_int *p;
  338. {
  339. int cr,type,doff;
  340.  
  341. type = p[-3].i;
  342. doff = p[-2].i;
  343. cr = p[-1].i;
  344. #ifdef DEBUG
  345. printf("cr %d type %d doff %d\n", cr, type, doff);
  346. #endif DEBUG
  347. if (!check_valid_creature("Cread", cr))
  348.     return(NULL);
  349. p = cr_data[cr];
  350. if (type != p[CTYPE].i)
  351.     {
  352.     runtime_err("Trying to read wrong type of creature");
  353.     }
  354. return(p[doff+SECRETS].p);
  355. }
  356.  
  357. do_cwrite(p)
  358. union pt_int *p;
  359. {
  360. int cr,type,doff;
  361. union pt_int *d;
  362.  
  363. type = p[-4].i;
  364. doff = p[-3].i;
  365. cr = p[-2].i;
  366. #ifdef DEBUG
  367. printf("cr %d type %d doff %d data\n", cr, type, doff, p[-1].i);
  368. #endif DEBUG
  369. if (!check_valid_creature("Cwrite", cr))
  370.     return(NULL);
  371. d = cr_data[cr];
  372. if (type != d[CTYPE].i)
  373.     {
  374.     runtime_err("Trying to write wrong type of creature");
  375.     }
  376. d[doff+SECRETS].p = p[-1].p;
  377. }
  378.  
  379.  
  380. closest_type(p)
  381. union pt_int *p;
  382. {
  383. int i, x, y;
  384. register int dx, dy;
  385. int closest;
  386. long distance, d;
  387. union pt_int *cdata;
  388. char *me;
  389.  
  390. distance = 1L<<30;
  391. closest = 0;
  392. me = p[-3].p;
  393. x = p[-2].i;
  394. y = p[-1].i;
  395. for (i=1; i<=cr_hi; i++)
  396.     {
  397.     if (cr_state[i] == CR_RUNNING)
  398.         {
  399.         cdata = cr_data[i];
  400.         if (strcmp(me, cdata[CNAME].p) == 0)
  401.             {
  402.             dx = x - cdata[CX].i;
  403.             dy = y - cdata[CY].i;
  404.             if (dx < 0)
  405.                 dx = -dx;
  406.             if (dy < 0)
  407.                 dy = -dy;
  408.             d = dx + dy;
  409.             if (d < distance)
  410.                 {
  411.                 closest = i;
  412.                 distance = d;
  413.                 }
  414.             }
  415.         }
  416.     }
  417. return(closest);
  418. }
  419.  
  420. closest_creature(p)
  421. union pt_int *p;
  422. {
  423. int i, x, y;
  424. int dx, dy;
  425. int closest;
  426. long distance, d;
  427. union pt_int *cdata;
  428. int me;
  429.  
  430. distance = 1L<<30;
  431. closest = 0;
  432. me = p[-3].i;
  433. x = p[-2].i;
  434. y = p[-1].i;
  435. for (i=1; i<=cr_hi; i++)
  436.     {
  437.     if (me != i)
  438.         {
  439.         if (cr_state[i] == CR_RUNNING)
  440.             {
  441.             cdata = cr_data[i];
  442.             dx = x - cdata[CX].i;
  443.             dy = y - cdata[CY].i;
  444.             d = mult_to_long(dx,dx) + mult_to_long(dy,dy);
  445.             if (d < distance)
  446.                 {
  447.                 closest = i;
  448.                 distance = d;
  449.                 }
  450.             }
  451.         }
  452.     }
  453. return(closest);
  454. }
  455.  
  456. named_creature(p)
  457. union pt_int *p;
  458. {
  459. char *name;
  460. union pt_int *cdata;
  461. int i;
  462.  
  463. name = p[-1].p;
  464. for (i=1; i<cr_hi; i++)
  465.     {
  466.     if (cr_state[i] == CR_RUNNING)
  467.         {
  468.         cdata = cr_data[i];
  469.         if (strcmp(name, cdata[CNAME].p) == 0)
  470.             return(i);
  471.         }
  472.     }
  473. return(0);
  474. }
  475.  
  476. exists_creature(p)
  477. union pt_int *p;
  478. {
  479. return(cexists(p[-1].i) );
  480. }
  481.  
  482.  
  483. creature_age(p)
  484. union pt_int *p;
  485. {
  486. int cr;
  487.  
  488. cr = p[-1].i;
  489. if (check_valid_creature("CreatureAge", cr) )
  490.     {
  491.     p = cr_data[cr];
  492.     return(p[CAGE].i);
  493.     }
  494. }
  495.  
  496.  
  497. creature_newborn(p)
  498. union pt_int *p;
  499. {
  500. int cr;
  501.  
  502. cr = p[-1].i;
  503. if (check_valid_creature("CreatureNewBorn", cr) )
  504.     {
  505.     p = cr_data[cr];
  506.     return(p[CNEW].i);
  507.     }
  508. }
  509.  
  510. creature_x(p)
  511. union pt_int *p;
  512. {
  513. int cr;
  514.  
  515. cr = p[-1].i;
  516. if (check_valid_creature("CreatureX", cr) )
  517.     {
  518.     p = cr_data[cr];
  519.     return(p[CX].i);
  520.     }
  521. }
  522.  
  523. creature_y(p)
  524. union pt_int *p;
  525. {
  526. int cr;
  527.  
  528. cr = p[-1].i;
  529. if (check_valid_creature("CreatureY", cr) )
  530.     {
  531.     p = cr_data[cr];
  532.     return(p[CY].i);
  533.     }
  534. }
  535.  
  536. char *
  537. creature_name(p)
  538. union pt_int *p;
  539. {
  540. int cr;
  541.  
  542. cr = p[-1].i;
  543. if (check_valid_creature("CreatureName", cr) )
  544.     {
  545.     p = cr_data[cr];
  546.     return(p[CNAME].p);
  547.     }
  548. }
  549.  
  550.  
  551.  
  552.